package com.bruce.config;

import com.bruce.bean.TaskInfo;
import com.bruce.job.MyJob;

import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.ApplicationContext;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * @Description: Quartz配置类
 */
@SpringBootConfiguration
public class QuartzConfig {

    @Autowired
    private ApplicationContext applicationContext;

    //任务调度器
    @Autowired
    private Scheduler scheduler;
    /**
     * 01-开启任务
     */
    public void startJob(){
        try {
            openJob(scheduler);
            //启动任务
            scheduler.start();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /**
     * 02-暂停某个任务(指的是频繁定时调度可以暂停,而不是暂停正在执行的任务)
     */
    public void pauseJob(String name,String group) throws Exception{
        //任务的标识类(组和名称标识一个任务)
        JobKey jobKey=new JobKey(name,group);
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if(jobDetail!=null){
            //暂停某个任务
            scheduler.pauseJob(jobKey);
        }else{
            System.out.println("该任务不存在!");
        }
    }

    /**
     * 03-查询所有的任务基本信息
     * @return
     */
    public List<TaskInfo> getAllJobsInfo() throws Exception{
        List<TaskInfo> list=new ArrayList<TaskInfo>();
        //所有任务组
        List<String> jobGroupNames = scheduler.getJobGroupNames();
        for (String jobGroupName : jobGroupNames) {
            // 通过groupname拿到所有的key
            Set<JobKey> jobKeys = scheduler.getJobKeys(GroupMatcher.<JobKey>groupEquals(jobGroupName));
            for (JobKey jobKey : jobKeys) {
                // 根据key拿到所有的trigger
                List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
                for (Trigger trigger : triggers) {
                    Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                    JobDetail jobDetail = scheduler.getJobDetail(jobKey);
                    String cronExpression=""; //cron表达式
                    String cronDescription=""; //描述信息
                    if(trigger instanceof CronTrigger){
                        CronTrigger cronTrigger=(CronTrigger)trigger;
                        //cron表达式
                        cronExpression = cronTrigger.getCronExpression();
                        cronDescription=cronTrigger.getDescription();
                    }
                    TaskInfo taskInfo=new TaskInfo();
                    taskInfo.setJobName(jobKey.getName());
                    taskInfo.setJobGroup(jobKey.getGroup());
                    taskInfo.setJobDescrption(jobDetail.getDescription());
                    taskInfo.setStatus(triggerState.name()); //任务的状态
                    taskInfo.setCronExpression(cronExpression);
                    taskInfo.setCronDescription(cronDescription);
                    list.add(taskInfo);
                }
            }
        }
        return list;
    }
    /**
     * 开启一个任务
     * @param scheduler
     */
    private void openJob(Scheduler scheduler){
        JobDataMap map=new JobDataMap();
        map.put("applicationContext",applicationContext);
        try {
            //1.创建一个JobDetail,就是开启了一个job1的任务
            JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
                    .usingJobData(map) //传递给job
                    .withIdentity("job1", "group1").build();
            //2.触发器表达式对象,每4s执行一次
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/4 * * * * ?");
            /**暂停补偿相关属性,需要结合一个参数才起作用*/
            /*cronScheduleBuilder.withMisfireHandlingInstructionDoNothing(); // 一个任务触发执行后,错过的任务就不执行了,执行下一个周期
            cronScheduleBuilder.withMisfireHandlingInstructionFireAndProceed();// 一个任务触发执行后立刻执行一次,之后周期性执行
            cronScheduleBuilder.withMisfireHandlingInstructionIgnoreMisfires(); // 类似第二个
            */
            //CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("30 25 16 * * ?");
            //3.准备一个触发器对象
            CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "triggergroup1")
                    .withSchedule(cronScheduleBuilder).build();
            //4.开始调度
            scheduler.scheduleJob(jobDetail,cronTrigger);
        } catch (SchedulerException e) {
            e.printStackTrace();
        } finally {

        }
    }

    /**
     * 04-恢复某个任务的执行
     * @param name
     * @param group
     */
    public void resumeJob(String name,String group) throws Exception{
        JobKey jobKey=new JobKey(name,group);
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if(jobDetail!=null){
            scheduler.resumeJob(jobKey);
        }else{
            System.out.println("要恢复的任务不存在！");
        }
    }


    /**
     * 05-删除某一个任务
     * @param name
     * @param group
     * @throws Exception
     */
    public void deleteJob(String name,String group) throws Exception{
        JobKey jobKey=new JobKey(name,group);
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if(jobDetail!=null){
            scheduler.deleteJob(jobKey);
        }else{
            System.out.println("要删除的任务不存在！");
        }
    }


    /**
     * 06-动态的修改任务执行的表达式，触发规则
     * @param name
     * @param group
     * @return
     */
    public boolean modifyJob(String name,String group,String newTime) throws Exception{
        Date date=null;
        TriggerKey triggerKey=new TriggerKey(name,group);
        Trigger trigger = scheduler.getTrigger(triggerKey);
        CronTrigger cronTrigger=null;
        if(trigger instanceof CronTrigger){
            cronTrigger=(CronTrigger)trigger;
            //表达式
            String cronExpression = cronTrigger.getCronExpression();
            if(!cronExpression.equalsIgnoreCase(newTime)){
                System.out.println("需要修改原来的表达式："+cronExpression+"为:"+newTime);
                CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(newTime);
                //新的触发器
                CronTrigger cronTrigger1 = TriggerBuilder.newTrigger().withIdentity(name, group).withSchedule(cronScheduleBuilder).build();
                // 重新调度一下trigger
                date = scheduler.rescheduleJob(triggerKey, cronTrigger1);
            }else{
                System.out.println("不用修改！和原来的一样！");
            }
        }
        if(date!=null){
            return true;
        }else{
            return false;
        }
    }

}
